<?php
namespace app\user\controller;

use app\user\model\WeixinPay;
use cmf\controller\UserBaseController;
use think\Db;

class WeixinController extends UserBaseController
{
    public $appid;

    public $secret;

    public $appid_fwh;

    public $secret_fwh;

    public function _initialize()
    {
        $this->appid_fwh = config("appid_fwh");
        $this->secret_fwh = config("secret_fwh");
        $this->appid = config("appid");
        $this->secret = config("secret");
        parent::_initialize();
    }

    public function getToken_fwh()
    {
        $tempfile = "token_fwh.json";
        if (!file_exists($tempfile)) {
            $myfile = fopen($tempfile, "w");
            fclose($myfile);
            chmod($tempfile, 0777);
        }
        $data = file_get_contents($tempfile);
        $data = json_decode($data, true);
        $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . $this->appid_fwh . "&secret=" . $this->secret_fwh;
        
        return $this->_getTokenByIdsFromServer($url, $data, $tempfile);
        
    }

    public function getToken()
    {
        $tempfile = "token.json";
        if (!file_exists($tempfile)) {
            $myfile = fopen($tempfile, "w");
            fclose($myfile);
            chmod($tempfile, 0777);
        }
        $data = file_get_contents($tempfile);
        $data = json_decode($data, true);
        $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . $this->appid . "&secret=" . $this->secret;
        
        return $this->_getTokenByIdsFromServer($url, $data, $tempfile);
    }

    private function _getTokenByIdsFromServer($url, $data, $tempfile){
        $time = time();
        if ($data) {
            if (($data['expires_in'] < $time) || !isset($data['access_token'])) {
                $data_fwq = file_get_contents($url);
                $data = json_decode($data_fwq, true);
                $data['expires_in'] = $data['expires_in']+ $time;
                file_put_contents($tempfile, json_encode($data));
                return $data['access_token'];
            } else {
                return $data['access_token'];
            }
        } else {
            $data_fwq = file_get_contents($url);
            $data = json_decode($data_fwq, true);
            $data['expires_in'] = $data['expires_in']+ 7200;
            file_put_contents($tempfile, json_encode($data));
            return $data['access_token'];
        }
    }

    // 获取服务号的用户授权token
    public function getToken_fwh_auth($code)
    {
        $tempfile = "token_fwh_auth.json";
        if (!file_exists($tempfile)) {
            $myfile = fopen($tempfile, "w");
            fclose($myfile);
            chmod($tempfile, 0777);
        }
        $data = file_get_contents($tempfile);
        $data = json_decode($data, true);
        $time = time();
        $url = "https://api.weixin.qq.com/sns/oauth2/access_token?code=$code&grant_type=authorization_code&appid=" . $this->appid_fwh . "&secret=" . $this->secret_fwh;
        if (isset($data['access_token'])) {
            if (!(($data['expires_in'] + 7200) >= $time) || !isset($data['access_token'])) {
                $data = file_get_contents($url);
                $data = json_decode($data, true);
                $data['expires_in'] = time();
                file_put_contents($tempfile, json_encode($data));
            }
        } else {
            $data = file_get_contents($url);
            $data = json_decode($data, true);
            $data['expires_in'] = time();
            file_put_contents($tempfile, json_encode($data));
        }
        return $data;
    }

    public static function execcommand($cmd)
    {
        error_reporting(E_ALL);
        set_time_limit(0);
        // echo "<h2>TCP/IP Connection</h2>\n";

        $port = 8889;
        $ip = "47.92.165.115";

        $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
        if ($socket < 0) {
            echo "socket_create() failed: reason: " . socket_strerror($socket) . "\n";
        } else {
            // echo "OK.\n";
        }
        $result = socket_connect($socket, $ip, $port);
        if ($result < 0) {
            echo "socket_connect() failed.\nReason: ($result) " . socket_strerror($result) . "\n";
        } else {
            // echo "连接OK\n";
        }

        $in = $cmd . "\n";
        $out = '';

        if (!socket_write($socket, $in, strlen($in))) {
            echo "socket_write() failed: reason: " . socket_strerror($socket) . "\n";
            return false;
        } else {
            // echo "write ok\n";
        }
        $out = "";
        while ($out = socket_read($socket, 8192)) {
            echo $out;
        }
        socket_close($socket);
        return $out;
    }

    public function getindusinfo()
    {
        set_time_limit(0);
        $imei = $_GET['imei'];
        $latitude = $_GET['latitude'];
        $longtitude = $_GET['longtitude'];
        $athome = $_GET['athome'];

        $user = Db::table("erxi_device_user")->where([
            'imei' => $imei,
            'is_sub' => 0
        ])->find();
        $device = Db::table("erxi_device")->where([
            'imei' => $imei,
        ])->find();
        // if ($device['text_number'] == 0) {
        //     return;
        // }

        $uid = $user['uid'];
        //判断上次发送时间
        // $msg_log = Db::table("erxi_template_msg_log")->where([
        //     'uid' => $uid,
        //     'msg_type' => 1
        // ])->order("create_time desc")->find();
        // if ($msg_log) {
        //     if (time() - $msg_log['create_time'] < 600000) {
        //         return;
        //     }
        // }

        $user = Db::table("erxi_user")->find($uid);

        $openid = $user['openid_fwh'];
        $token = $this->getToken_fwh();
        $url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={$token}";
        if (isset($latitude) && isset($longtitude)) {
            $loc = $latitude . "," . $longtitude;
            $location = file_get_contents("http://apis.map.qq.com/ws/geocoder/v1/?location=$loc&key=4BKBZ-BYPL6-GSCSX-EWQPG-MZCYH-UCBZI");
            $location = json_decode($location, true);
        }
        $device_name = $device['device_name'] ? $device['device_name'] : $imei;
        $msg = [
            'touser' => $openid,
            'template_id' => 'UltYqv2kDazyXW3x9MwL2VmcM-oPsd5g2YldO1naUJ0',
            'url' => '',
            'data' => [
                'first' => [
                    'value' => $device_name . "家长，请注意！ 设备监测到" . $device_name . "在过去一小时里，出现过跨越安全区域的的迹象。",
                    'color' => "#173177",
                ],
                'keyword1' => [
                    'value' => $location['result']['formatted_addresses']['recommend'],
                    'color' => "#173177",
                ],
                'keyword2' => [
                    'value' => date("Y-m-d H:i:s"),
                    'color' => "#173177",
                ],
                'remark' => [
                    'value' => '为了宠物安全，请您及时查看宠物当前情况。',
                    'color' => "#173177",
                ],
            ],
        ];
        $content = $this->post_curls($url, json_encode($msg));
        $content = json_decode($content, true);

        if ($content['errcode'] != 0) {
            $data1['errmsg'] = $content['errmsg'];
            $data1['errcode'] = $content['errcode'];
            // if ($data1['errcode'] == 0) {
            //     $device['text_number'] -= 1;
            //     Db::table("erxi_device")->where([
            //         'imei' => $imei,
            //     ])->update(['text_number' => $device['text_number']]);
            // }
            $data1['msgid'] = isset($content['msgid']) ? $content['msgid'] : null;
            $data1['uid'] = $uid;
            $data1['create_time'] = time();
            $data1['msg_type'] = 1; // 围栏提醒
            Db::table("erxi_template_msg_log")->insert($data1);
        }
        return json_encode($content);
    }

    public function electricQuantityInfo()
    {
        set_time_limit(0);
        $imei = $_GET['imei'];
        $latitude = $_GET['latitude'];
        $longtitude = $_GET['longtitude'];
        $electricQuantity = $_GET['electricQuantity'];


        $user = Db::table("erxi_device_user")->where([
            'imei' => $imei,
        ])->find();
        $device = Db::table("erxi_device")->where([
            'imei' => $imei,
        ])->find();
        // if ($device['text_number'] == 0) {
        //     return;
        // }

        $uid = $user['uid'];
        
        //判断上次发送时间
        // $msg_log = Db::table("erxi_template_msg_log")->where([
        //     'uid' => $uid,
        //     'msg_type' => 2
        // ])->order("create_time desc")->find();
        // if ($msg_log) {
        //     if (time() - $msg_log['create_time'] < 600) {
        //         return;
        //     }
        // }

        $user = Db::table("erxi_user")->find($uid);

        $openid = $user['openid_fwh'];
        $token = $this->getToken_fwh();
        $url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={$token}";
        if (($latitude!=null) && ($longtitude!=null)) {
            $loc = $latitude . "," . $longtitude;
            $location = file_get_contents("http://apis.map.qq.com/ws/geocoder/v1/?location=$loc&key=4BKBZ-BYPL6-GSCSX-EWQPG-MZCYH-UCBZI");
            $location = json_decode($location, true);
        }
        $device_name = $device['device_name'] ? $device['device_name'] : $imei;
        
        if ($electricQuantity == 10) {
            $first_value = $device_name . "家长请注意！设备电量已达到10%，请及时充电。";
        } else {
            $first_value = $device_name . "家长请注意！设备电量已低于5%，请及时充电。";
        }
        $msg = [
            'touser' => $openid,
            'template_id' => 'Qnc7INQY8fza4aB5AX-9FV6WKi5oku1ypONHhHOcMjk',
            'url' => '',
            'data' => [
                'first' => [
                    'value' => $first_value,
                    'color' => "#173177",
                ],
                'keyword1' => [
                    'value' => date("Y-m-d H:i:s"),
                    'color' => "#173177",
                ],
                'keyword2' => [
                    'value' => $location['result']['formatted_addresses']['recommend'],
                    'color' => "#173177",
                ],
                'remark' => [
                    'value' => 'Tips:电子围栏功能会以10分钟一次的频率进行定位。使用灯光功能也会影响待机时间。在无必要的情况下，建议关闭这两项功能。',
                    'color' => "#173177",
                ],
            ],
        ];
        $content = $this->post_curls($url, json_encode($msg));
        $content = json_decode($content, true);
        
        if ($content['errcode'] != 0) {
            $data1['errmsg'] = $content['errmsg'];
            $data1['errcode'] = $content['errcode'];
            $data1['msg_type'] = 2; //电量提醒
            // if ($data1['errcode'] == 0) {
            //     $device['text_number'] -= 1;
            //     Db::table("erxi_device")->where([
            //         'imei' => $imei,
            //     ])->update(['text_number' => $device['text_number']]);
            // }
            $data1['msgid'] = isset($content['msgid']) ? $content['msgid'] : null;
            $data1['uid'] = $uid;
            $data1['create_time'] = time();
            Db::table("erxi_template_msg_log")->insert($data1);
        }
        return json_encode($content);
    }

    public function post_curls($url, $post)
    {
        $curl = curl_init(); // 启动一个CURL会话
        curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检查
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); // 从证书中检查SSL加密算法是否存在
        curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模拟用户使用的浏览器
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转
        curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自动设置Referer
        curl_setopt($curl, CURLOPT_POST, 1); // 发送一个常规的Post请求
        curl_setopt($curl, CURLOPT_POSTFIELDS, $post); // Post提交的数据包
        curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循环
        curl_setopt($curl, CURLOPT_HEADER, 0); // 显示返回的Header区域内容
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 获取的信息以文件流的形式返回
        $res = curl_exec($curl); // 执行操作
        if (curl_errno($curl)) {
            echo 'Errno' . curl_error($curl); // 捕抓异常
        }
        curl_close($curl); // 关闭CURL会话
        return $res; // 返回数据，json格式
    }

    public function getsessionkey()
    {
        $code = $this->request->param("code", '', "string");
        $token = $this->getToken();
        $appid = config("appid");
        $secret = config("secret");
        $url = "https://api.weixin.qq.com/sns/jscode2session?appid=$appid&secret=$secret&js_code=$code&grant_type=authorization_code";
        return cmf_curl_get($url);
    }

    // 获取服务号的用户信息
    public function getFuwuhaoUserinfo()
    {
        $appid = $this->appid_fwh;
        $code = $_GET['code'];
        $data = $this->getToken_fwh_auth($code);
        $access_token = $data['access_token'];
        $openid = $data['openid'];
        $url = "https://api.weixin.qq.com/sns/userinfo?access_token=$access_token&openid=$openid&lang=zh_CN";
        $userinfo = file_get_contents($url);
        $userinfo = json_decode($userinfo, true);
        $unionid = $userinfo['unionid'];
        $openid = $userinfo['openid'];
        $user_fwu = Db::table("erxi_user")->where([
            'openid_fwh' => $openid,
        ])->find();
        if ($user_fwu) {
            $this->success('已经绑定', url("/portal/index/bind"));
        }
        $user = Db::table("erxi_user")->where([
            'unionid' => $unionid,
        ])->find();
        if ($user) {
            $user['openid_fwh'] = $openid;
            $result = Db::table("erxi_user")->where([
                'id' => $user['id'],
            ])->update($user);
            if ($result) {
                $this->success('绑定成功', url("/portal/index/bind"));
            } else {
                $this->success('绑定失败', url("/portal/index/bind"));
            }
        }
    }

    // 调用微信支付统一下单接口
    public function getWxPrepay()
    {
        $appid = $this->appid;
        $mch_id = "1502435691";
        $notify_url = "http://www.ju2xi.com/user/order/new";
        $key = "ej5fKKRmQEA7vuWPGvWxQG5ZFXkFmS3B";
        $openid = $_GET['openid'];
        $item_id = $_GET['item_id'];
        $device_id = $_GET['device_id'];
        $uid = $_GET['uid'];
        $total_fee = $_GET['total_fee'];
        $spbill_create_ip = $_SERVER['REMOTE_ADDR'];
        // 下订单，获取订单id
        $wechatAppPay = new WeixinPay($appid, $mch_id, $notify_url, $key, $openid, $spbill_create_ip);
        $order_id = $this->generatorOrder($item_id, $uid, $total_fee, $device_id);

        $params['body'] = '商品描述'; // 商品描述
        $params['out_trade_no'] = $order_id; // 自定义的订单号
        $params['total_fee'] = $total_fee * 100; // 订单金额 只能为整数 单位为分
        $params['trade_type'] = 'JSAPI'; // 交易类型 JSAPI | NATIVE | APP | WAP
        $result = $wechatAppPay->unifiedOrder($params);
        // print_r($result); // result中就是返回的各种信息信息，成功的情况下也包含很重要的prepay_id
        // 2.创建APP端预支付参数
        /** @var TYPE_NAME $result */
        if (!isset($result['prepay_id'])) {
            return json_encode([
                'msg' => $result,
            ]);
        }
        $data = $wechatAppPay->getAppPayParams($result['prepay_id']);
        $data['order_id'] = $order_id;
        return json_encode($data);
    }

    // 生成订单
    public function generatorOrder($item_id, $uid, $total_fee, $device_id)
    {
        $time = date("YmdHis");
        $order_id = $time . $this->getRandCode();
        $data['order_id'] = $order_id;
        $data['create_time'] = time();
        $data['item_id'] = $item_id;
        $data['status'] = 0;
        $data['uid'] = $uid;
        $data['device_id'] = $device_id;
        $data['money'] = $total_fee;
        Db::table('erxi_order')->insert($data);
        return $order_id;
    }

    // 支付完成之后处理订单状态
    public function handleOrderAfterPay()
    {
        $order_id = $_GET['order_id'];
        $status = $_GET['status'];
        $uid = $_GET['uid'];
        $total_fee = $_GET['total_fee'];
        $result_pay = true;
        $create_time = time();
        $order = Db::table('erxi_order')->where([
            'order_id' => $order_id,
        ])->find();
        if ($status == 1) {
            $result_pay = Db::table('erxi_pay_log')->insert([
                'order_id' => $order_id,
                'uid' => $uid,
                'create_time' => $create_time,
                'money' => $total_fee,
            ]);

            $item = Db::table('erxi_item')->find($order['item_id']);
            $item_type = $item['type'];
            $device_id = $order['device_id'];
            $number = $item['number'];
            $device = Db::table('erxi_device')->find($device_id);
            // 设备年费
            if ($item_type == 1) {
                $number = $number * 30 * 3600 * 24;
                $device['effect_time'] += $number;
                Db::table('erxi_device')->where([
                    'id' => $device_id,
                ])->update([
                    'effect_time' => $device['effect_time'],
                ]);
            } elseif ($item_type == 2) {
                $device['number'] += $number;
                Db::table('erxi_device')->where([
                    'id' => $device_id,
                ])->update([
                    'number' => $number,
                ]);
            }
            Db::table('erxi_order')->where([
                'order_id' => $order_id,
            ])->update([
                'status' => 1,
            ]);
        } else {
            $result = Db::table('erxi_order')->where([
                'order_id' => $order_id,
            ])->delete();
        }
        if ($result_pay) {
            $msg = "支付成功";
            $return_status = true;
        } else {
            $msg = "支付失败";
            $return_status = false;
        }
        return json_encode([
            'msg' => $msg,
            'status' => $return_status,
        ]);
    }

    // 生成随机字符串
    public function getRandCode()
    {
        $charts = "0123456789";
        $max = strlen($charts);
        $noncestr = "";
        for ($i = 0; $i < 6; $i++) {
            $noncestr .= $charts[mt_rand(0, 9)];
        }
        return $noncestr;
    }

    public function deleteDeviceDataByDaily()
    {
        $time = (time() - 3600 * 24 * 3) * 1000;
        // Db::table("erxi_device_data")->where('create_time','<', $time)->delete();
        // echo Db::table("erxi_device_data")->getLastSql();

        $sql = "DELETE FROM `erxi_device_data` WHERE `create_time` < $time";
        Db::execute($sql);
    }
}
